package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.commons.utils.DateConversionUtils;
import com.tanhua.commons.utils.JwtUtils;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.db.*;
import com.tanhua.model.vo.CountsVo;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.UserLikeListVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;

/**
 * @auther : 白月尘
 * @date : 14:46  2021/10/16
 */
@Service
public class UserService {

    @DubboReference
    private FreezeApi freezeApi;

    @DubboReference
    private UserApi userApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    @DubboReference
    private FriendApi friendApi;

    @DubboReference
    private UserLikeToApi userLikeToApi;

    @Autowired
    private MqMessageService mqMessageService;

    public Map findByMobile(String mobile, String verificationCode) {
        User user = userApi.findByMobile(mobile);
        String code = redisTemplate.opsForValue().get("Code_" + mobile);
        if (StringUtils.isEmpty(code) || !verificationCode.equals(code)) {
            throw new BusinessException(ErrorResult.loginError());
        }
        redisTemplate.delete("Code_" + mobile);
        boolean isNew = false;
        if (user == null) {
            user = new User();
            user.setMobile(mobile);
            user.setPassword(DigestUtils.md5Hex("123456"));
            long userId = userApi.insert(user);
            user.setId(userId);
            isNew = true;
            huanXinTemplate.createUser("hx" + userId, Constants.INIT_PASSWORD);
            user.setHxUser("hx" + userId);
            user.setHxPassword(Constants.INIT_PASSWORD);
            userApi.update(user);
        }
        mqMessageService.sendLogService(user.getId(), isNew ? "0102" : "0101", "user", null);
        Map tokenMap = new HashMap();
        tokenMap.put("id", user.getId());
        tokenMap.put("mobile", mobile);
        String token = JwtUtils.getToken(tokenMap);
        Map map = new HashMap();
        map.put("isNew", isNew);
        map.put("token", token);
        return map;
    }

    public void sendMsg(String mobile) {
        String code = RandomUtil.randomNumbers(6);
        redisTemplate.opsForValue().set("Code_" + mobile, code, Duration.ofMinutes(5));
        System.out.println(code);
    }

    public boolean checkVerificationCode(String verificationCode) {
        String mobile = UserHolder.getMobile();
        User user = userApi.findByMobile(mobile);
        String code = redisTemplate.opsForValue().get("Code_" + mobile);
        if (StringUtils.isEmpty(code) || !verificationCode.equals(code)) {
            throw new BusinessException(ErrorResult.loginError());
        }
        redisTemplate.delete("Code_" + mobile);
        boolean isNew = false;
        if (user != null) {
            return true;
        }
        return false;
    }

    public void setPhone(String phone) {
        long userId = UserHolder.getUserId();
        userApi.setPhone(userId, phone);
    }


    //校验账号冻结状态
    public void checkFreezeState(String mobile) {

        User user = userApi.findByMobile(mobile);
        Freeze freeze = freezeApi.selectByUid(user.getId());
        if (freeze == null) {
            this.sendMsg(mobile);
        } else if (freeze.getFreezingRange() == 2 || freeze.getFreezingRange() == 3) {
            this.sendMsg(mobile);
        }
        // 冻结范围：1为冻结登录，2为冻结发言，3为冻结发布动态
        if (freeze != null && freeze.getFreezingRange() == 1) {
            Date currentDate = DateConversionUtils.parseStrToDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                    .format(new Date()), "yyyy-MM-dd HH:mm:ss", new Date());
            Date unfreezeTime = freeze.getUnfreezeTime();
            Long timeDifference = freezeApi.selectFreezeTimeDifference(currentDate, unfreezeTime);
            if (timeDifference <= 0) {
                //已到解封时间
                freeze.setIsFreezing(1);//1解冻，2冻结
                freeze.setReasonsForThawing(DateUtil.now() + "到期自动解冻~");
                freezeApi.updateById(freeze);
                sendMsg(mobile);
            } else {
                //当前用户被冻结
                throw new BusinessException(ErrorResult.FreezeLoginError(freeze.getUnfreezeTime()));
            }
        }

    }

    /**
     * 互相喜欢、喜欢、粉丝、谁看过我 - 翻页列表
     */
    public PageResult findfriends(int type, int page, int pagesize) {
        Long userId = UserHolder.getUserId();
        switch (type) {
            case 1:
                //1 互相关注
                return eachLove(page, pagesize, userId);
            case 2:
                //2 我关注
                return love(page, pagesize, userId);
            case 3:
                //3 粉丝
                return Fan(page, pagesize, userId);
            case 4:
                //4 谁看过我
                return attention(page, pagesize, userId);
            default:
                return new PageResult();

        }
    }

    //1 互相关注
    public PageResult eachLove(Integer page, Integer pagesize, Long userId) {
        String isLike = "true";
        List<UserLike> fanAll = userLikeToApi.findLoveAll(userId, isLike);
        if (fanAll == null || fanAll.size() <= 0) {
            return new PageResult();
        }
        List<Long> userIds = CollUtil.getFieldValues(fanAll, "likeUserId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findAll(userIds);
        List<UserLikeListVo> vos = new ArrayList<>();
        for (UserLike userLike : fanAll) {
            UserInfo userInfo = map.get(userLike.getLikeUserId());
            UserLikeListVo vo = UserLikeListVo.init(userInfo, userLike);
            vos.add(vo);
        }
        return new PageResult(page, pagesize, 0l, vos);
        // List<UserLike> loveAll = userLikeToApi.findLoveAll(userId,isLike);
        // List<Long> likeUserIds = CollUtil.getFieldValues(loveAll, "likeUserId", Long.class);
        // List<UserLike> fanAll = userLikeToApi.findFanAll(userId,isLike);
        // List<Long> userIds = CollUtil.getFieldValues(fanAll, "userId", Long.class);
        // List<Long> duplicate = findDuplicate(likeUserIds, userIds);
        // if(duplicate==null || duplicate.size()<=0){
        //     return new PageResult();
        // }
        // List<UserLike> eachLove = new ArrayList<>();
        // for (Long likeUserId : duplicate) {
        //     UserLike userLikeTo = userLikeToApi.findeachLove(userId,likeUserId,isLike);
        //     eachLove.add(userLikeTo);
        // }
        // Map<Long, UserInfo> map = userInfoApi.findIds(duplicate);
        // List<UserLikeListVo> vos = new ArrayList<>();
        // for (UserLike userLike : eachLove) {
        //     UserInfo userInfo = map.get(userLike.getLikeUserId());
        //     UserLikeListVo vo = UserLikeListVo.init(userInfo, userLike);
        //     vos.add(vo);
        // }
        // return new PageResult(page, pagesize, 0l, vos);
    }

    //2 我关注
    public PageResult love(Integer page, Integer pagesize, Long userId) {
        String isLike = "false";
        System.out.println("islike：" + isLike);
        //根据用户id查询喜欢
        List<UserLike> loveAll = userLikeToApi.findLoveAll(userId, isLike);
        System.out.println("用户喜欢：" + loveAll);
        if (loveAll == null || loveAll.size() <= 0) {
            return new PageResult();
        }
        List<Long> likeUserIds = CollUtil.getFieldValues(loveAll, "likeUserId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findIds(likeUserIds);
        System.out.println("map:" + map);
        List<UserLikeListVo> vos = new ArrayList<>();
        for (UserLike userLike : loveAll) {
            UserInfo userInfo = map.get(userLike.getLikeUserId());
            UserLikeListVo vo = UserLikeListVo.init(userInfo, userLike);
            vos.add(vo);
        }
        return new PageResult(page, pagesize, 0l, vos);
    }

    //3 粉丝
    public PageResult Fan(Integer page, Integer pagesize, Long userId) {
        String isLike = "false";
        List<UserLike> fanAll = userLikeToApi.findFansiAll(userId);
        if (fanAll == null || fanAll.size() <= 0) {
            return new PageResult();
        }
        List<Long> userIds = CollUtil.getFieldValues(fanAll, "userId", Long.class);
        System.out.println(userIds);
        Map<Long, UserInfo> map = userInfoApi.findAll(userIds);
        List<UserLikeListVo> vos = new ArrayList<>();
        for (UserLike userLike : fanAll) {
            UserInfo userInfo = map.get(userLike.getUserId());
            UserLikeListVo vo = UserLikeListVo.init(userInfo, userLike);
            vos.add(vo);
        }
        return new PageResult(page, pagesize, 0l, vos);

    }

    //谁关注我
    public PageResult attention(Integer page, Integer pagesize, Long userId) {
        List<Visitors> list = visitorsApi.findFriendsByUserId(page, pagesize, userId);
        if (list.size() <= 0 || list == null) {
            return new PageResult();
        }
        List<Long> ids = CollUtil.getFieldValues(list, "visitorUserId", Long.class);

        Map<Long, UserInfo> map = userInfoApi.findIds(ids);
        List<UserLikeListVo> vos = new ArrayList<>();
        for (Visitors visitors : list) {
            UserInfo userInfo = map.get(visitors.getVisitorUserId());
            UserLikeListVo init = UserLikeListVo.init(userInfo, visitors);
            vos.add(init);
        }

        String key = Constants.VISITORS_USER + userId;
        Long date = System.currentTimeMillis();
        redisTemplate.opsForValue().set(key, date.toString());

        return new PageResult(page, pagesize, 0l, vos);
    }


    /**
     * 互相喜欢，喜欢，粉丝 - 统计
     * eachLoveCount  互相喜欢	loveCount 喜欢  fanCount   粉丝
     */
    public CountsVo counts() {
        Long userId = UserHolder.getUserId();
        String isLike = "true";
        //根据用户id查询喜欢
        List<UserLike> loveAll = userLikeToApi.findLoveAll(userId, "false");
        List<Long> likeUserIds = CollUtil.getFieldValues(loveAll, "likeUserId", Long.class);
        Integer loveCount = loveAll.size();
        //根据用户id查询粉丝
        List<UserLike> fanAll = userLikeToApi.findFanAll(userId, isLike);
        //List<Long> userIds = CollUtil.getFieldValues(fanAll, "userId", Long.class);
        Integer fanCount = fanAll.size();
        //查询互相喜欢
        List<UserLike> duplicate = userLikeToApi.findFanAll(userId,"true");
        Integer eachLoveCount = duplicate.size();
        CountsVo vo = new CountsVo(eachLoveCount, loveCount, fanCount);
        return vo;
    }

    //获取相同数据
    private static List<Long> findDuplicate(List<Long> list1, List<Long> list2) {
        List<Long> duplicate = new ArrayList<Long>();
        Map<Long, Integer> map = new HashMap<Long, Integer>();
        //1.去重
        List<Long> list3 = new ArrayList<Long>(new HashSet<Long>(list1));
        List<Long> list4 = new ArrayList<Long>(new HashSet<Long>(list2));
        //2.将list中的元素加入map中并进行统计
        for (Long s1 : list1) {
            map.put(s1, 1);
        }
        //3.将list中的元素加入map中并进行统计
        for (Long s2 : list2) {
            map.put(s2, (map.get(s2) == null ? 1 : 2));
        }
        //4.将重复的元素放入list中
        for (Map.Entry<Long, Integer> m : map.entrySet()) {
            if (m.getValue() == 2) {
                duplicate.add(m.getKey());
            }
        }
        return duplicate;
    }

    //粉丝 - 喜欢
    public void fans(Long likeUserId) {
        String isLike = "true";
        Long userId = UserHolder.getUserId();
        Boolean exist = userLikeToApi.findExist(userId, likeUserId);
        loveAndUnlove(userId, likeUserId, isLike, exist);
        huanXinTemplate.addContact("hx" + userId, "hx" + likeUserId);
        friendApi.save(userId, likeUserId);
    }

    //取消喜欢
    public void unlike(Long likeUserId) {
        String isLike = "false";
        Long userId = UserHolder.getUserId();
        Boolean exist = userLikeToApi.findExist(userId, likeUserId);
        loveAndUnlove(userId, likeUserId, isLike, exist);
        //取消好友关系(环信)
        huanXinTemplate.deleteContact("hx" + userId, "hx" + likeUserId);
        //取消friend表
        friendApi.delete(userId, likeUserId);
    }

    public void loveAndUnlove(Long userId, Long likeUserId, String isLike, Boolean b) {
        UserLike userLike = new UserLike();
        if (!b) {
            userLike.setUserId(userId);
            userLike.setLikeUserId(likeUserId);
            userLike.setIsLike(Boolean.valueOf(isLike));
            userLike.setCreated(System.currentTimeMillis());
            userLike.setUpdated(System.currentTimeMillis());
            userLikeToApi.save(userLike);
        } else {
            userLike.setUserId(userId);
            userLike.setLikeUserId(likeUserId);
            userLike.setIsLike(Boolean.valueOf(isLike));
            userLikeToApi.update(userLike);
        }
    }
}
